package cn.maihe.elg.operation.supports.electronicseal.anne;

import cn.maihe.elg.operation.model.enums.AuditStatusEnum;
import cn.maihe.elg.operation.model.enums.BidCustomerStatus;
import cn.maihe.elg.operation.repository.entity.BidCustomerDO;
import cn.maihe.elg.operation.repository.entity.BidCustomerDOCondition;
import cn.maihe.elg.operation.repository.entity.OrganizationDO;
import cn.maihe.elg.operation.repository.entity.OrganizationDOCondition;
import cn.maihe.elg.operation.service.business.BidCustomerService;
import cn.maihe.elg.operation.service.system.OrganizationService;
import cn.maihe.elg.operation.supports.electronicseal.anne.bean.annesign.base.SecureApiResponse;
import cn.maihe.elg.operation.supports.electronicseal.anne.bean.annesign.enterprise.vo.EnterpriseResult;
import cn.maihe.elg.operation.supports.electronicseal.anne.bean.annesign.notice.ContractSignerStatusChangeNotifyRequest;
import cn.maihe.elg.operation.supports.electronicseal.anne.bean.annesign.notice.EnterpriseStatusChangeNotifyRequest;
import cn.maihe.elg.operation.supports.electronicseal.anne.bean.annesign.notice.NotifyBaseRequest;
import cn.maihe.elg.operation.supports.electronicseal.anne.service.impl.AnneApiParamService;
import cn.maihe.elg.operation.supports.electronicseal.anne.utils.annesign.AnneSignConst;
import cn.maihe.elg.operation.supports.electronicseal.anne.utils.annesign.JsonUtils;
import cn.maihe.elg.operation.supports.electronicseal.anne.utils.annesign.NotifyConst;
import cn.maihe.framework.starter.mybatis.dao.MybatisDaoImpl;
import cn.maihe.framework.starter.mybatis.mapper.PlusEntityWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @Description
 * @Author WJH
 * @Date 2021/08/10
 */
@RequestMapping
@RestController
@Slf4j
public class AnneSignCallbackHandler {

    @Resource
    private AnneSignService anneSignService;
    @Resource
    private AnneApiParamService anneApiParamService;
    @Resource
    private OrganizationService organizationService;
    @Resource
    private BidCustomerService bidCustomerService;

    @PostMapping(AnneSignConst.CALLBACK_NOTIFY_URL)
    public SecureApiResponse notify(@RequestBody String requestJson) {
        log.info("安妮回调通知报文:{}", requestJson);
        String secretKey = anneApiParamService.getSecretKey();

        NotifyBaseRequest request = JsonUtils.fromJson(requestJson, NotifyBaseRequest.class);
        if (!request.getSign(secretKey).equals(request.getSign())) {
            return setSecureApiResponse(request.getUuid(), secretKey, AnneSignConst.RESPONSE_FAIL_CODE, "验签失败");
        }

        if (NotifyConst.BIZ_TYPE_CONTRACT.equals(request.getBody().getBizType())) {
            if (NotifyConst.MSG_TYPE_SIGNER_STATUS_CHANGE.equals(request.getBody().getMsgType())) {
                return changeContractStatus(requestJson, secretKey);
            }
        } else if (NotifyConst.BIZ_TYPE_ENTERPRISE.equals(request.getBody().getBizType())) {
            if (NotifyConst.MSG_TYPE_STATUS_CHANGE.equals(request.getBody().getMsgType())) {
                return changeEnterpriseStatus(requestJson, secretKey);
            }
        }
        return setSecureApiResponseSuccess(request.getUuid(), secretKey);
    }

    private SecureApiResponse changeEnterpriseStatus(String requestJson, String secretKey) {
        EnterpriseStatusChangeNotifyRequest request = JsonUtils.fromJson(requestJson, EnterpriseStatusChangeNotifyRequest.class);
        /**企业状态，0：待审核，5：审核失败，9：审核通过（详见数据字典：auditStatus）*/
        String status = request.getBody().getStatus();
        String auditOpinion = request.getBody().getAuditOpinion();
        //内部系统统一社会信用代码一定唯一
        String licenseCode = request.getBody().getLicenseCode();
        Long enterpriseId = request.getBody().getEnterpriseId();
        String auditDesc = auditOpinion;

        EnterpriseResult enterpriseResult;
        if ("5".equals(status)) {
            enterpriseResult = new EnterpriseResult(EnterpriseStatus.AUDIT_REJECT, auditOpinion, enterpriseId);
        } else if ("9".equals(status)) {
            enterpriseResult = new EnterpriseResult(EnterpriseStatus.AUDIT_PASS, auditOpinion, enterpriseId);
        } else if ("0".equals(status)) {
            enterpriseResult = new EnterpriseResult(EnterpriseStatus.AUDITING, auditOpinion, enterpriseId);
        } else {
            log.error("未识别的企业({})创建审核状态[{}:{}],暂不处理", licenseCode, status, auditOpinion);
            return setSecureApiResponse(secretKey, request.getUuid(), 400, "未知审核状态[status:" + status + "],暂不处理");
        }

        if (StringUtils.isNotBlank(licenseCode)) {
            Integer aCount = MybatisDaoImpl.run().selectCount(OrganizationDOCondition.builder().andCreditCodeEq(licenseCode).build());
            if (aCount != null && aCount == 1) {
                //创建机构企业回调
                doUpdateByOrg(licenseCode, enterpriseResult);
            } else if (aCount != null && aCount > 1) {
                //异常处理：信用代码不唯一或不存在
                log.error("担保企业[{}]不存在或信用代码不唯一,数据错误，暂确认后处理.审核状态【{}:{}】", licenseCode, status, auditOpinion);
                return setSecureApiResponse(secretKey, request.getUuid(), 400, "licenseCode不存在或非唯一性");
            } else {

                Integer bCount = MybatisDaoImpl.run().selectCount(BidCustomerDOCondition.builder().andBidderCreditCodeEq(licenseCode).build());
                if (bCount != null && bCount == 1) {
                    //创建投标企业回调
                    doUpdateByBidder(licenseCode, enterpriseResult);
                } else {
                    //异常处理：信用代码不唯一或不存在
                    log.error("投标企业[{}]不存在或信用代码不唯一,数据错误，暂确认后处理.审核状态【{}:{}】", licenseCode, status, auditOpinion);
                    return setSecureApiResponse(secretKey, request.getUuid(), 400, "licenseCode不存在或非唯一性");
                }
            }

        } else {
            return setSecureApiResponse(secretKey, request.getUuid(), 400, "licenseCode不能为空");
        }
        return setSecureApiResponseSuccess(request.getUuid(), secretKey);
    }

    private void doUpdateByBidder(String licenseCode, EnterpriseResult enterpriseResult) {
        EnterpriseStatus enterpriseStatus = enterpriseResult.getStatus();
        BidCustomerStatus status = null;

        if (enterpriseStatus == EnterpriseStatus.AUDIT_PASS) {
            status = BidCustomerStatus.NORMAL;
        } else if (enterpriseStatus == EnterpriseStatus.AUDIT_REJECT) {
            status = BidCustomerStatus.AUDIT_FAIL;
        } else if (enterpriseStatus == EnterpriseStatus.AUDITING) {
            status = BidCustomerStatus.AUDIT_OUTER;
        }
        if (status != null) {
            BidCustomerDO updateDO = BidCustomerDO.builder().status(status.getStatus()).auditDesc(enterpriseResult.getAuditDesc()).enterpriseId(enterpriseResult.getEnterpriseId()).build();
            PlusEntityWrapper<BidCustomerDO> condition = BidCustomerDOCondition.builder().andBidderCreditCodeEq(licenseCode).andStatusEq(AuditStatusEnum.AUDIT_OUT.getValue()).build();
            MybatisDaoImpl.run().update(updateDO, condition);
        }
    }

    /**
     * 更新机构企业状态
     */
    private void doUpdateByOrg(String licenseCode, EnterpriseResult enterpriseResult) {
        EnterpriseStatus enterpriseStatus = enterpriseResult.getStatus();
        AuditStatusEnum status = null;
        /**业务状态**/
        Integer businessStatus = null;
        if (enterpriseStatus == EnterpriseStatus.AUDIT_PASS) {
            status = AuditStatusEnum.AUDITED;
            businessStatus = 1;
        } else if (enterpriseStatus == EnterpriseStatus.AUDIT_REJECT) {
            status = AuditStatusEnum.AUDIT_REJECT;
            businessStatus = 0;
        } else if (enterpriseStatus == EnterpriseStatus.AUDITING) {
            status = AuditStatusEnum.AUDIT_OUT;
        }
        if (status != null) {
            OrganizationDO updateDO = OrganizationDO.builder().auditStatus(status.getValue()).businessStatus(businessStatus).auditDesc(enterpriseResult.getAuditDesc()).enterpriseId(enterpriseResult.getEnterpriseId()).build();
            PlusEntityWrapper<OrganizationDO> condition = OrganizationDOCondition.builder().andCreditCodeEq(licenseCode).andAuditStatusEq(AuditStatusEnum.AUDIT_OUT.getValue()).build();
            MybatisDaoImpl.run().update(updateDO, condition);
        }
    }

    private SecureApiResponse changeContractStatus(String requestJson, String secretKey) {
//        TODO
        ContractSignerStatusChangeNotifyRequest request = JsonUtils.fromJson(requestJson, ContractSignerStatusChangeNotifyRequest.class);
//        String contractStatus = request.getBody().getContractStatus();
//        Long contractId = request.getBody().getContractId();
//        String thirdContractId = request.getBody().getThirdContractId();
//        if (thirdContractId.startsWith(AnneSignConst.CONTRACT_TYPE_BH)) {
////            orderService.updateAnneSignContractStatus(contractStatus, contractId);
//        } else if (thirdContractId.startsWith(AnneSignConst.CONTRACT_TYPE_SQ)) {
////            cooperateCompanyService.updateAnneSignContractStatus(contractStatus, contractId);
//        }
        return setSecureApiResponseSuccess(request.getUuid(), secretKey);
    }

    private SecureApiResponse setSecureApiResponseSuccess(String secretKey, String uuid) {
        return setSecureApiResponse(secretKey, uuid, AnneSignConst.RESPONSE_OK_CODE, AnneSignConst.RESPONSE_OK_DETAIL);
    }

    private SecureApiResponse setSecureApiResponse(String secretKey, String uuid, Integer code, String detail) {
        SecureApiResponse response = new SecureApiResponse();
        response.setTimestamp(System.currentTimeMillis());
        response.setUuid(uuid);
        response.setVersion(AnneSignConst.API_VERSION_1);
        response.setDetail(detail);
        response.setCode(code);
        response.setSign(response.getSign(secretKey));
        return response;
    }
}
